home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / AOF / DECAOF / decaof / io_c < prev    next >
Text File  |  1992-11-20  |  6KB  |  301 lines

  1. /*
  2.  * file input/output
  3.  *
  4.  * Andy Duplain, BT Customer Systems, Brighton, UK.  duplain@btcs.bt.co.uk
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include "decaof.h"
  9. #include "cproto.h"
  10. #include "error.h"
  11.  
  12. #if defined(BSD42) || defined(SYSV2)
  13. extern char *malloc P__((unsigned len));
  14. #else
  15. #include <malloc.h>
  16. #endif
  17.  
  18. /*
  19.  * check for EOF or write/read errors on stream.
  20.  */
  21. Ferror
  22. check_stream(fp)
  23.     FILE *fp;
  24. {
  25.     int ret = FNOERR;
  26.  
  27.     if (feof(fp))
  28.         ret = FEND;
  29.     else if (ferror(fp))
  30.         ret = FRWERR;
  31.     if (ret != FNOERR)
  32.         clearerr(fp);
  33.     return (ret);
  34. }
  35.  
  36. /*
  37.  * read a byte from the input stream.
  38.  */
  39. Byte
  40. read_byte(ifp)
  41.     FILE *ifp;
  42. {
  43.     return ((Byte)getc(ifp));
  44. }
  45.  
  46. /*
  47.  * read a little-endian 2-byte halfword from the input stream.
  48.  */
  49. Halfword
  50. read_halfword(ifp)
  51.     FILE *ifp;
  52. {
  53.     union {
  54.         Halfword h;
  55.         Byte b[sizeof(Halfword)];
  56.     } ret;
  57.  
  58. #if defined(LITTLE_ENDIAN)
  59.     fread((char *)&ret.h, 1, sizeof(Halfword), ifp);
  60. #else
  61.     ret.b[HALFWORD0] = read_byte(ifp);
  62.     ret.b[HALFWORD1] = read_byte(ifp);
  63. #endif
  64.     return (ret.h);
  65. }
  66.  
  67. /*
  68.  * read a little-endian 4-byte word from the input stream.
  69.  */
  70. Word
  71. read_word(ifp)
  72.     FILE *ifp;
  73. {
  74.     union {
  75.         Word w;
  76.         Byte b[sizeof(Word)];
  77.     } ret;
  78.  
  79. #if defined(LITTLE_ENDIAN)
  80.     fread((char *)&ret.w, 1, sizeof(Word), ifp);
  81. #else
  82.     ret.b[WORD0] = read_byte(ifp);
  83.     ret.b[WORD1] = read_byte(ifp);
  84.     ret.b[WORD2] = read_byte(ifp);
  85.     ret.b[WORD3] = read_byte(ifp);
  86. #endif
  87.     return (ret.w);
  88. }
  89.  
  90. /*
  91.  * read in the chunk header
  92.  */
  93. struct chunkhdr *
  94. read_chunkhdr(ifp)
  95.     FILE *ifp;
  96. {
  97.     static struct chunkhdr hdr;
  98.  
  99.     fseek(ifp, 0L, 0);
  100.     hdr.chunkfileid = read_word(ifp);
  101.     hdr.maxchunks = read_word(ifp);
  102.     hdr.numchunks = read_word(ifp);
  103.     return (check_stream(ifp) != FRWERR ? &hdr : NULL);
  104. }    
  105.  
  106. /*
  107.  * memory pointers maintained by read_xxx functions
  108.  */
  109.  
  110. static struct chunkent *ents = NULL;    /* chunk file entries */
  111. static char *strptr = NULL;        /* string table */
  112. static struct symbol *symptr = NULL;    /* symbol table */
  113. static char *idptr = NULL;        /* identification string */
  114. static struct aofhdr *aofhdr = NULL;    /* AOF header */
  115.  
  116. /*
  117.  * free the memory used by a chunk
  118.  */
  119. int
  120. free_chunk_memory(ptr)
  121.     char *ptr;
  122. {
  123.     if (!ptr)
  124.         return (0);
  125.  
  126.     if (ptr == (char *)ents) {
  127.         free(ents);
  128.         ents = NULL;
  129.     } else if (ptr == strptr) {
  130.         free(strptr);
  131.         strptr = NULL;
  132.     } else if (ptr == (char *)symptr) {
  133.         free(symptr);
  134.         symptr = NULL;
  135.     } else if (ptr == idptr) {
  136.         free(idptr);
  137.         idptr = NULL;
  138.     } else if (ptr == (char *)aofhdr) {
  139.         free(aofhdr);
  140.         aofhdr = NULL;
  141.     } else
  142.         return (-1);
  143.     return (0);
  144. }    
  145.  
  146. /*
  147.  * read in the chunk entries
  148.  */
  149. struct chunkent *
  150. read_chunkents(ifp, hdr)
  151.     FILE *ifp;
  152.     struct chunkhdr *hdr;
  153. {
  154.     register i;
  155.  
  156.     if (ents)
  157.         free(ents);
  158.     ents = (struct chunkent *)malloc(
  159.         sizeof(struct chunkent) * hdr->maxchunks);
  160.     if (!ents) {
  161.         error("memory exhausted");
  162.         abort();
  163.     }
  164.         
  165.     fseek(ifp, sizeof(struct chunkhdr), 0);
  166.     for (i = 0; i < hdr->numchunks; i++) {
  167.         fread(ents[i].chunkid, 1, 8, ifp);
  168.         ents[i].offset = read_word(ifp);
  169.         ents[i].size = read_word(ifp);
  170.     }
  171.  
  172.     return (check_stream(ifp) != FRWERR ? ents : NULL);
  173. }
  174.  
  175. /*
  176.  * read in the string table
  177.  */
  178. char *
  179. read_stringtab(ifp, strent)
  180.     FILE *ifp;
  181.     struct chunkent *strent;
  182. {
  183.     if (strptr)
  184.         free(strptr);
  185.     strptr = malloc(strent->size);
  186.     if (!strptr) {
  187.         error("memory exhausted");
  188.         abort();
  189.     }
  190.     
  191.     fseek(ifp, strent->offset, 0);
  192.     *(Word *)strptr = read_word(ifp);    /* size in 1st word */
  193.     fread(strptr + 4, 1, (int)strent->size - 4, ifp);
  194.  
  195.     return (check_stream(ifp) != FRWERR ? strptr : NULL);
  196. }
  197.  
  198. /*
  199.  * read in the symbol table
  200.  */
  201. struct symbol *
  202. read_symboltab(ifp, syment, numsyms)
  203.     FILE *ifp;
  204.     struct chunkent *syment;
  205.     int numsyms;
  206. {
  207.     register i;
  208.  
  209.     if (symptr)
  210.         free(symptr);
  211.     symptr = (struct symbol *)malloc(numsyms * sizeof(struct symbol));
  212.     if (!symptr) {
  213.         error("memory exhausted");
  214.         abort();
  215.     }
  216.     
  217.     fseek(ifp, syment->offset, 0);
  218.     for (i = 0; i < numsyms; i++) {
  219.         symptr[i].name = read_word(ifp);
  220.         symptr[i].flags = read_word(ifp);
  221.         symptr[i].value = read_word(ifp);
  222.         symptr[i].areaname = read_word(ifp);
  223.     }
  224.  
  225.     return (check_stream(ifp) != FRWERR ? symptr : NULL);
  226. }
  227.  
  228. /*
  229.  * read in the identification chunk
  230.  */
  231. char *
  232. read_ident(ifp, ident)
  233.     FILE *ifp;
  234.     struct chunkent *ident;
  235. {
  236.     if (idptr)
  237.         free(idptr);
  238.     idptr = malloc(ident->size);
  239.     if (!idptr) {
  240.         error("memory exhausted");
  241.         abort();
  242.     }
  243.  
  244.     fseek(ifp, (long)ident->offset, 0);
  245.     fread(idptr, 1, (int)ident->size, ifp);
  246.  
  247.     return (check_stream(ifp) != FRWERR ? idptr : NULL);
  248. }
  249.  
  250. /*
  251.  * read in the AOF header
  252.  */
  253. struct aofhdr *
  254. read_aofhdr(ifp, hdrent)
  255.     FILE *ifp;
  256.     struct chunkent *hdrent;
  257. {
  258.     register i;
  259.     struct areahdr *areahdr;
  260.  
  261.     if (aofhdr)
  262.         free(aofhdr);
  263.     aofhdr = (struct aofhdr *)malloc(hdrent->size);
  264.     if (!aofhdr) {
  265.         error("memory exhausted");
  266.         abort();
  267.     }
  268.  
  269.     /* read-in whole of AOF header */
  270.     fseek(ifp, hdrent->offset, 0);
  271.     aofhdr->filetype = read_word(ifp);
  272.     aofhdr->version = read_word(ifp);
  273.     aofhdr->numareas = read_word(ifp);
  274.     aofhdr->numsyms = read_word(ifp);
  275.     aofhdr->entryarea = read_word(ifp);
  276.     aofhdr->entryoffset = read_word(ifp);
  277.     areahdr = (struct areahdr *)(aofhdr + sizeof(struct aofhdr));
  278.     for (i = 0; i < aofhdr->numareas; i++) {
  279.         areahdr[i].name = read_word(ifp);
  280.         areahdr[i].flags = read_word(ifp);
  281.         areahdr[i].size = read_word(ifp);
  282.         areahdr[i].numrelocs = read_word(ifp);
  283.         areahdr[i].reserved = read_word(ifp);
  284.     }
  285.     return (check_stream(ifp) != FRWERR ? aofhdr : NULL);
  286. }
  287.  
  288. /*
  289.  * read in a relocation directive
  290.  */
  291. struct reloc *
  292. read_reloc(ifp)
  293.     FILE *ifp;
  294. {
  295.     static struct reloc reloc;
  296.  
  297.     reloc.offset = read_word(ifp);
  298.     reloc.flags = read_word(ifp);
  299.     return (check_stream(ifp) != FRWERR ? &reloc : NULL);
  300. }
  301.